﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Consul;
using HttpProvider;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Zd.MicroService.Client.Models;

namespace Zd.MicroService.Client.Controllers
{
    public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;

        public HomeController(ILogger<HomeController> logger) {
            _logger = logger;
        }

        private static int ISeed = 0;
        public IActionResult Index() {
            //接口，为什么不见IP和端口是因为Consul把同类服务做成群，所以只需要用群名就能获取对应功能的所有站点
            string url = "http://ZdConsulService/api/data"; 
            Uri uri = new Uri(url);
            string groupName = uri.Host;
            string content = "";

            using (ConsulClient consul = new ConsulClient(c => {
                c.Address = new Uri("http://localhost:8500");
                c.Datacenter = "dc1";
            })) {
                //服务实例在Consul是以键值对形式摆放的
                Dictionary<string, AgentService> dicServices = consul.Agent.Services().Result.Response;
                var lstServices = dicServices
                    .Where(t => t.Value.Service.Equals(groupName, StringComparison.OrdinalIgnoreCase));
                //var firstService = lstServices.First(); //获取groupName第一个注册进Consul的实例
                // 均衡策略
                //var rd = new Random();
                //int index = rd.Next(0, lstServices.Count());
                //var service = lstServices.ElementAt(index);
                // 轮询策略
                //var service = lstServices.ElementAt(ISeed++ % lstServices.Count());
                // 权重策略 Tags我传的是 new string[]{启动时传进来的权重环境变量}
                Dictionary<string, int> weights = lstServices
                    .Select(t => new KeyValuePair<string, int>(t.Key, Convert.ToInt32(t.Value.Tags[0])))
                    .ToDictionary(k => k.Key, v => v.Value);
                List<KeyValuePair<string, AgentService>> services = new List<KeyValuePair<string, AgentService>>();
                for (int i=0; i<weights.Count; i++) {
                    var item = weights.ElementAt(i);
                    var itemService = lstServices.First(t => t.Key == item.Key);
                    //按权重新增加实例个数
                    for (int j = 0; j <= item.Value; j++) {
                        services.Add(itemService);
                    }
                }
                //通过Random随机获取
                var rd = new Random();
                int index = rd.Next(0, lstServices.Count());
                var service = services.ElementAt(index);

                //拼接数据url 并调用
                string tagetUrl = 
                    $"{uri.Scheme}://{service.Value.Address}:{service.Value.Port}{uri.PathAndQuery}";
                content = HttpHelper.Get(tagetUrl).Result;

                //将请求到的数据发送到页面, 这里我把端口也输出了方便看效果
                ViewData["Content"] = $"{service.Value.Port} --> {content}"; 
            }

            return View();
        }

        public IActionResult Privacy() {
            return View();
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error() {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }
}
